#include "shapeutils.h"
#include <QPixmap>
#include <QImage>
#include <math.h>
#include "collisionshapes.h"
#include "collisionshapesdocument.h"

void findMinMaxValues(int x, int y, int& minX, int& maxX, int& minY, int& maxY)
{
    if(x < minX)
    {
        minX = x;
    }

    if(x > maxX)
    {
        maxX = x;
    }

    if(y < minY)
    {
        minY = y;
    }

    if(y > maxY)
    {
        maxY = y;
    }
}

int alphaValue(int x, int y, const QImage& image)
{
    QRgb rgb = image.pixel(x, y);
    return qAlpha(rgb);
}

void calculateSilhouette(QPointer<CollisionShapesDocument> csDoc, const QPixmap& pm, const QRect &pmRect)
{
    Q_ASSERT(!pm.isNull());

    QImage image = pm.toImage();

    int minX = pmRect.width();
    int maxX = 0;
    int minY = pmRect.height();
    int maxY = 0;

    int startX = pmRect.left();
    int startY = pmRect.top();

    for(int y=startY;y<startY + pmRect.height();++y)
    {
        for(int x=startX;x<startX + pmRect.width();++x)
        {
            findMinMaxValues(x, y, minX, maxX, minY, maxY);
        }
    }

    int radius = std::max(minX, maxX);
    radius = std::max(radius, minY);
    radius = std::max(radius, maxY);

    QPointer<CollisionShape> circle = csDoc->createCircleShape(QPointF(0, 0), radius);
    QList<QPointer<CollisionPoly> > polys = circle->toPolygon(csDoc, 32);

    foreach(QPointer<CollisionPoly> polyShape, polys)
    {
        QPolygonF poly = polyShape->poly();

        for(int i=0;i<3;i++)
        {
            QPointF pt = poly[i];

            if(!pt.isNull())
            {
                QPointF vec = -pt;
                float length = sqrt(vec.x()*vec.x() + vec.y()*vec.y());
                QPointF normalizedVec = vec/length;

                while(1)
                {
                    float realLength = sqrt(pt.x()*pt.x() + pt.y()*pt.y());

                    if(length < 2)
                    {
                        break;
                    }

                    if(alphaValue(pmRect.width()/2 + pt.x(), pmRect.height()/2 + pt.y(), image) < 128)
                    {
                        pt += normalizedVec;
                    }
                    else
                    {
                        break;
                    }
                }

                poly[i] = pt;
            }
        }

        polyShape->setPoly(poly);
    }
}
